<?php
/**
 * DataGrid helper
 *
 * Affichage normalisé de données sur plusieures pages
 *
 * @uses viewHelper Zend_View_Helper
 */
class Jnd_View_Helper_DataGrid extends Zend_View_Helper_Abstract
{

    protected $_link = array();

    /**
     * Normalisation du tableau d'information sur la colonne
     *
     * @param  array $columnData
     * @return array
     */
    protected function _getColumnData($columnData)
    {
        $defaultData = array('visible' => true, 'search' => true);
        if (is_string($columnData)) {
            $columnData = array('name' => $columnData);
        } else if (! is_array($columnData)) {
            throw new Zend_Exception('Donnée invalide pour la colonne ' . get_class(
                $this));
        }
        $columnData = array_merge($defaultData, $columnData);
        if (! isset($columnData['name'])) {
            throw new Zend_Exception('Pas de nom de colonne fournit ' . get_class(
                $this));
        }
        return $columnData;
    }

    /**
     * Création du lien lié à une colonne
     *
     * @param string $idColumn
     * @param array $row
     * @param array $linkData
     */
    protected function _getLink($idColumn, $row, $linkData)
    {
        // Paramètre de la colonne
        $link = $this->_link;
        if (is_array($linkData)) {
            $link = array_merge($link, $linkData);
        }
        
        if (isset($link['clePrimaire'])) {
            $clePrimaire = $link['clePrimaire'];
        } else {
            $clePrimaire = "id";
        }
        
        // URL statique
        if (isset($link['url'])) {
            return $link['url'];
        }
        // Appel d'un callback
        if (isset($link['callback'])) {
            if (! is_callable($link['callback'])) {
                throw new Jnd_Exception("Callback invalide " . get_class(
                    $this) . "::_getLink");
            }
            return call_user_func($link['callback'], $idColumn, $row,
                $link);
        }
        // Utilisation de smartUrl
        return $this->view->smartUrl(
            $link['action'], $link['controller'], $link['module'],
            array($clePrimaire => $row[$idColumn]));
    }

    /**
     * Affichage d'un tableau basé sur des données fournies en paramètre.
     * $header :
     * array (
     * 'nom_colonne' => array(
     * 'name'   => 'nom d'affichage', // Nom de la colonne
     * ['link' => array(              // Defini un lien pour le contenu de la colonne
     * 'url'        => 'http://...'
     * OU
     * 'callback'   => ...
     * OU
     * 'action'     => 'editer',
     * 'controller' => 'controller',
     * 'module'     => 'module',
     * ),]
     * ['search' => true,] // Ajoute un champs de recherche
     * [visible' => true,] // Colonne visible ou invisible
     * )
     *
     * $options
     * array(
     * 'callback' => ...  // Callback de transformation
     * ['link' => array(
     * cf. $header
     * ),}
     * 'pageNumber' => (int)      // Page en cours
     * 'pageItemPerPage' => (int) // Nombre d'élément par page
     * 'form' => $form            // Formulaire contenant les éléments de filtrage
     * )
     *
     * @param array $header Entete de colonne avec parametres
     * @param Zend_Db_Table_Select $data Données à afficher
     * @param string $idColumn Colonne des données utilisée comme clef primaire
     * @param array $options Options d'affichage
     * @param Ddb_Model_Mapper_Abstract $mapper
     */
    public function dataGrid($header, $data, $idColumn, array $options = array())
    {
        $html = '';
        // Initialisation du lien par défaut
        $this->_link = array('action' => null,
            'controller' => null, 'module' => null);
        // Récupération des options générales
        if (isset($options['link']) && is_array(
            $options['link'])) {
            $this->_link = array_merge($this->_link, $options['link']);
        }
        // Création du paginateur
        $paginator = Zend_Paginator::factory(
            $data);
        $paginator->setPageRange(
            isset($options['pageRange']) ? $options['pageRange'] : 10);
        $paginator->setCurrentPageNumber(
            isset($options['pageNumber']) ? $options['pageNumber'] : 1);
        $paginator->setItemCountPerPage(
            isset($options['pageItemPerPage']) ? $options['pageItemPerPage'] : 10);
        // Normalisation des données
        foreach ($header as $column => $columnData) {
            $header[$column] = $this->_getColumnData($columnData);
        }
        // Création de la balise formulaire
        if (isset($options['form'])) {
            $html .= '<form name="' . $options['form']->getName() . '" action="' . $options['form']->getAction() . '" method="' . $options['form']->getMethod() . '" enctype="' . $options['form']->getEnctype() . '">';
        }
        $html .= '<table cellpadding="0" cellspacing="0" style="border: 0px" width="100%" class="beautableau">';
        $html .= '<thead>';
        $html .= '<tr>';
        // Affichage de l'entête
        $columnNumber = 0;
        foreach ($header as $column => $columnData) {
            if (! $columnData['visible']) {
                continue;
            }
            $html .= '    <th>' . __($columnData['name']) . '</th>';
            $columnNumber ++;
        }
        $html .= '<th>&nbsp;</th></tr>';
        $html .= '</thead>';
        $html .= '<tbody>';
        // Si un formulaire est fournit, affiche la barre de filtrage
        if (isset($options['form'])) {
            $form = $options['form'];
            $html .= '<tr>';
            $first = true;
            foreach ($header as $column => $columnData) {
                if (! $columnData['visible']) {
                    continue;
                }
                if ($first) {
                    $balise = 'th';
                    $first = false;
                } else {
                    $balise = 'td';
                }
                if (isset($form->$column) && $columnData['search']) {
                    $html .= '    <' . $balise . '>' . $form->$column . '</' . $balise . '>';
                } else {
                    $html .= '    <' . $balise . '>&nbsp;</' . $balise . '>';
                }
            }
            $html .= '<td style="white-space: nowrap"><input type="image" src="' . $this->view->baseUrl(
                '/images/chercher_gris.png') . '" />&nbsp;<img src="' . $this->view->baseUrl(
                '/images/supprimer_gris.png') . '" style="border: 0px" class="lien" onclick="location.href=\'' . $options['form']->getAction() . '\'" alt="" /></td>';
            $html .= '</tr>';
        }
        // Affichage des données
        foreach ($paginator as $row) {
            // transformation des données
            if (isset(
                $options['callback'])) {
                if (! is_callable($options['callback'])) {
                    throw new Zend_Exception('Callback invalide pour le helper ' . get_class(
                        $this));
                }
                // Passage par référence de l'enregistrement
                call_user_func_array(
                    $options['callback'],
                    array(&$row,
                        $this->view));
            }
            $html .= '<tr class="' . ($this->view->cycle(
                array('odd', ''))->next()) . '">';
            // Affichage des données par colonne
            $balise = 'th';
            foreach ($header as $column => $columnData) {
                if (! $columnData['visible']) {
                    continue;
                }
                $lien = $this->_getLink($idColumn, $row,
                    isset(
                        $columnData['link']) ? $columnData['link'] : null);
                $html .= '    <' . $balise . '><a href="' . $lien . '">' . $this->view->escape(
                    $row[$column]) . '</a></' . $balise . '>';
                $balise = 'td';
            }
            if (isset($options['form'])) {
                $html .= '<td>&nbsp;</td>';
            }
            $html .= '</tr>';
        }
        $html .= '</tbody>';
        $html .= '<tfoot>';
        $html .= '    <tr>';
        $html .= '        <td colspan="' . ($columnNumber + (isset($options['form']) ? 1 : 0)) . '" align="center">' . $paginator . '</td>';
        $html .= '    </tr>';
        $html .= '</tfoot>';
        $html .= '</table>';
        if (isset($options['form'])) {
            $html .= '</form>';
        }
        return $html;
    }
}

